package com.douya.common.pojo.dto;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.douya.common.utils.StringUtils;
import com.github.yulichang.query.MPJQueryWrapper;
import com.google.common.collect.Lists;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 说明：分页信息对象
 *
 * @Author 胡晨烨
 * @Date 2020/02/01
 */
@Slf4j
@Getter
@Setter
@Accessors(chain = true)
public class PagerDTO {

    /**
     * 当前页数，总1开始
     */
    private Integer current = 1;

    /**
     * 每页条数
     */
    private Integer size = 10;

    /**
     * 需要进行排序的字段
     */
    private String column;
    /**
     * 是否正序排列，默认 true
     */
    private Boolean asc = true;

    /**
     * 多列排序时使用
     */
    private List<OrderItem> sorts;

    /**
     * 组装好的查询条件，最终查询以此为准
     */
    private List<ConditionDTO> conditions;

    /**
     * 分页组装
     *
     * @return 分页对象
     */
    @SuppressWarnings("rawtypes,unchecked")
    public <T> IPage<T> toPage(T t) {
        Page page = new Page<>(this.current, this.size);
        List<OrderItem> sortList = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(this.sorts)) {
            sortList.addAll(this.sorts);
        } else {
            if (StringUtils.isNotBlank(this.column)) {
                OrderItem orderItem = new OrderItem();
                orderItem.setColumn(StringUtils.camelToUnderline(this.column));
                orderItem.setAsc(asc);
                sortList.add(orderItem);
            }
        }
        if (CollectionUtils.isNotEmpty(sortList)) {
            List<OrderItem> itemList = sortList.stream()
                    .peek(item -> item.setColumn(StringUtils.camelToUnderline(item.getColumn())))
                    .collect(Collectors.toList());
            page.setOrders(itemList);
        }
        return page;
    }


    /**
     * 连表条件
     *
     * @param t   实体类
     * @param <T> 泛型
     * @return 连表条件
     */
    public <T> MPJQueryWrapper<T> toMpjQuery(T t) {
        MPJQueryWrapper<T> queryWrapper = new MPJQueryWrapper<T>();
        if (CollectionUtils.isNotEmpty(this.conditions)) {
            this.conditions.forEach(condition -> {
                if (Objects.nonNull(condition.getCompare())) {
                    String underline = StringUtils.camelToUnderline(condition.getName());
                    ConditionDTO.CompareType type = condition.realCompare();
                    switch (type) {
                        case EQ:
                            queryWrapper.eq(underline, condition.realValue());
                            break;
                        case NE:
                            queryWrapper.ne(underline, condition.realValue());
                            break;
                        case GT:
                            queryWrapper.gt(underline, condition.realValue());
                            break;
                        case GE:
                            queryWrapper.ge(underline, condition.realValue());
                            break;
                        case LT:
                            queryWrapper.lt(underline, condition.realValue());
                            break;
                        case LE:
                            queryWrapper.le(underline, condition.realValue());
                            break;
                        case LIKE:
                            queryWrapper.like(underline, condition.realValue());
                            break;
                        case NOT_LIKE:
                            queryWrapper.notLike(underline, condition.realValue());
                            break;
                        case IN:
                            queryWrapper.in(underline, condition.realValue());
                            break;
                        case NOT_IN:
                            queryWrapper.notIn(underline, condition.realValue());
                            break;
                        case NULL:
                            queryWrapper.isNull(underline);
                            break;
                        case NOT_NULL:
                            queryWrapper.isNotNull(underline);
                            break;
                        default:
                            break;
                    }
                }
            });
        }
        return queryWrapper;
    }

    /**
     * 查询条件
     *
     * @param t   实体类
     * @param <T> 泛型
     * @return 连表条件
     */
    public <T> QueryWrapper<T> toQuery(T t) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<T>();
        if (CollectionUtils.isNotEmpty(this.conditions)) {
            this.conditions.forEach(condition -> {
                if (Objects.nonNull(condition.getCompare())) {
                    String underline = StringUtils.camelToUnderline(condition.getName());
                    ConditionDTO.CompareType type = condition.realCompare();
                    switch (type) {
                        case EQ:
                            queryWrapper.eq(underline, condition.realValue());
                            break;
                        case NE:
                            queryWrapper.ne(underline, condition.realValue());
                            break;
                        case GT:
                            queryWrapper.gt(underline, condition.realValue());
                            break;
                        case GE:
                            queryWrapper.ge(underline, condition.realValue());
                            break;
                        case LT:
                            queryWrapper.lt(underline, condition.realValue());
                            break;
                        case LE:
                            queryWrapper.le(underline, condition.realValue());
                            break;
                        case LIKE:
                            queryWrapper.like(underline, condition.realValue());
                            break;
                        case NOT_LIKE:
                            queryWrapper.notLike(underline, condition.realValue());
                            break;
                        case IN:
                            queryWrapper.in(underline, condition.realValue());
                            break;
                        case NOT_IN:
                            queryWrapper.notIn(underline, condition.realValue());
                            break;
                        case NULL:
                            queryWrapper.isNull(underline);
                            break;
                        case NOT_NULL:
                            queryWrapper.isNotNull(underline);
                            break;
                        default:
                            break;
                    }
                }
            });
        }
        return queryWrapper;
    }

}
